/****************************************Copyright (c)****************************************************

**--------------File Info---------------------------------------------------------------------------------
** File name:                sht40.c
** Last modified Date:       2024.11.14
** Last Version:             Ver:1.0
** Descriptions:             SHT40温湿度IC驱动
**
**--------------------------------------------------------------------------------------------------------
** Created by:               adm
** Created date:             2024.11.14
** Version:                  Ver:1.0
** Descriptions:             使用本驱动，需要调用i2c_application中间件
**--------------------------------------------------------------------------------------------------------*/
#include "sht40.h"

i2c_handle_type hi2c2_SHT40;


/**
  * @brief        CRC8校验函数
  * @param    待计算的数据指针，CRC计算初始值，一般为0xFF
  * @retval      返回计算后的校验码
  */
uint8_t SHT40_CheckCrc8(uint8_t* const message, uint8_t initial_value)
{
    uint8_t  remainder;     //余数
    uint8_t  i = 0, j = 0;  //循环变量

    /* 初始化 */
    remainder = initial_value;

    for(j = 0; j < 2; j++) {
        remainder ^= message[j];

        /* 从最高位开始依次计算  */
        for (i = 0; i < 8; i++) {
            if (remainder & 0x80) {
                remainder = (remainder << 1)^CRC8_POLYNOMIAL;
            } else {
                remainder = (remainder << 1);
            }
        }
    }

    /* 返回计算的CRC码 */
    return remainder;
}


/**
  * @brief    SHT40_Read_Temperature_Humidity
  *           以高精度读取温度和湿度,不对CRC校验码做验证
  * @param    Temperature温度指针，Humidity湿度指针
  * @retval   None
  */
void SHT40_Read_Temperature_Humidity(float *Temperature, float *Humidity)
{
    uint32_t Temperature_Byte;
    uint32_t Temperature_Checksum;
    uint32_t Humidity_Byte;
    uint32_t Humidity_Checksum;
    double   temp, hum;

    uint8_t I2C_Transmit_Data[1];
    uint8_t I2C_Receive_Data[6] = {0};

    I2C_Transmit_Data[0] = SHT40_CMD_MEASURE_HPM;

    i2c_master_transmit(&hi2c2_SHT40, SHT40_ADDRESS, I2C_Transmit_Data, 1, 0xFFFFF);
    #if USE_RTOS
    vTaskDelay(10);
    #else
    wk_delay_ms(10);
    #endif
    i2c_master_receive(&hi2c2_SHT40, SHT40_ADDRESS, I2C_Receive_Data, 6, 0xFFFFF);

    Temperature_Byte = I2C_Receive_Data[0] << 8 | I2C_Receive_Data[1];
    Temperature_Checksum = SHT40_CheckCrc8(&I2C_Receive_Data[0], 0xFF);
    Humidity_Byte = I2C_Receive_Data[3] << 8 | I2C_Receive_Data[4];
    Humidity_Checksum = SHT40_CheckCrc8(&I2C_Receive_Data[3], 0xFF);
    temp = -45.0f + 175.0f * (float)Temperature_Byte / 65535.0f;
    hum = -6.0f + 125.0f * (float)Humidity_Byte / 65535.0f;

    if(hum > 100.0f) hum = 100.0f;

    if(hum < 0.0f) hum = 0.0f;

    *Temperature = temp;
    *Humidity = hum;
}


/**
  * @brief    SHT40_Read_Serial_Number
  *           读取SHT40的出场唯一序列号
  * @param    None
  * @retval   32bit的序列号
  */
uint32_t SHT40_Read_Serial_Number(void)
{
    uint32_t Serial_Number;
    uint8_t I2C_Transmit_Data[1];
    uint8_t I2C_Receive_Data[6];

    I2C_Transmit_Data[0] = SHT40_CMD_READ_SERIAL;

    i2c_master_transmit(&hi2c2_SHT40, SHT40_ADDRESS, I2C_Transmit_Data, 1, 0xFFFFF);
    i2c_master_receive(&hi2c2_SHT40, SHT40_ADDRESS, I2C_Receive_Data, 6, 0xFFFFF);

    Serial_Number = (I2C_Receive_Data[0] << 24) |
                    (I2C_Receive_Data[1] << 16) |
                    (I2C_Receive_Data[3] << 8) |
                    (I2C_Receive_Data[4] << 0);

    return Serial_Number;
}


/**
  * @brief    SHT40_Heater_200mW_1s
  *           开始内部加热器，以200mW加热1秒（一秒）
  *           加热时间不能超过运行时间的10％，否则会过热。详情说明请参考数据手册12页
  * @param    None
  * @retval   None
  */
void SHT40_Heater_200mW_1s(void)
{
    uint8_t I2C_Transmit_Data[1];

    I2C_Transmit_Data[0] = SHT40_CMD_200W_1S;
    i2c_master_transmit(&hi2c2_SHT40, SHT40_ADDRESS, I2C_Transmit_Data, 1, 0xFFFFF);
}


/**
  * @brief    SHT40初始化
  * @param    None
  * @retval   None
  */
void SHT40_Init(void)
{
    hi2c2_SHT40.i2cx = I2C2;
    i2c_config(&hi2c2_SHT40);
}
